package core.algorithm.operator.Selection;

import core.controllers.ControlDynamicParameters;
import core.problem.Individual;
import core.tools.MyMath.RandomGenerator;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author 郝国生 HAO Guo-Sheng 选择算子通用功能
 */
public class SelectionCommonFunction {

    List<Individual> populationList = new LinkedList<>();

    public List<Individual> getSelectionResult(List<Individual> individualList, double[] fitness) {
        //不同的选择算子，最小值会不同
        List<Individual> result = new LinkedList<>();
        //适应值规范化到[0,1]之间
        double[] proUpLowNo;
        if (ControlDynamicParameters.selectionType == 2) {//RankSelection
            proUpLowNo = fitness;
        } else {
            proUpLowNo = normalizeData2ndStep(fitness);
        }
        double temf;
        for (Individual indi : individualList) {
            temf = RandomGenerator.nextDouble();//生成的随机数在0与所有个体的适应值之和之间
//            System.out.println("最大值为："+proUpLowNo[proUpLowNo.length-1]+"，产生的随机数为："+temf);
            int j = 0;
            for (Individual indj : individualList) {//遍历，找到对应的个体
                if (temf >= proUpLowNo[j] && temf < proUpLowNo[j + 1]) {
                    try {
                        result.add((indj).clone());
                    } catch (CloneNotSupportedException ex) {
                        Logger.getLogger(SelectionCommonFunction.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    break;
                }
                j++;
            }
        }
        assert result.size() == ControlDynamicParameters.populationSize;
        return result;
    }

    private double[] normalizeData2ndStep(double[] fitness) {
        double[] result = new double[fitness.length + 1];
        double sum = 0;
        for (int i = 0; i < fitness.length; i++) {
            assert fitness[i] >= 0;
            sum += fitness[i];
        }
        for (int i = 1; i <= fitness.length; i++) {
            result[i] = result[i - 1] + fitness[i - 1] / sum;
        }
        result[fitness.length] = 1.0;
        return result;
    }

    public static void main(String[] args) {
        int size = 4;
        SelectionCommonFunction scf = new SelectionCommonFunction();
        double[] data = new double[size];
        for (int i = 1; i <= size; i++) {
            data[i - 1] = i;
        }
        double[] sele = scf.normalizeData2ndStep(data);
        for (int i = 0; i < sele.length; i++) {
            System.out.println(sele[i]);
        }
    }
}
